<template>
    <div style="height: 100%">
        <!-- 表格上面的功能栏 -->
        <div v-if="hasTop" class="table-search marb-5">
            <!-- 普通搜索 -->
            <div style="display: flex; align-items: center; justify-content: space-between; height: 32px">
                <div>
                    <!-- 添加按钮 -->
                    <div v-if="hasAdd" class="fl marr-5">
                        <el-button @click="onShowDetail" type="primary">
                            <el-icon>
                                <Plus />
                            </el-icon>
                        </el-button>
                    </div>

                    <!-- 搜索文本框 -->
                    <!-- 不要这种模糊的多搜索条件，by：李昊 -->
                    <!-- <div v-if="hasInput" class="fl marr-5">
                        <el-input class="placeholder-center" v-model="searchInput" :placeholder="inputTips" @change="onInputChange" clearable></el-input>
                    </div> -->

                    <!-- 其它要放到表头的搜索条件 -->
                    <div class="fl searchGroup">
                        <slot name="otherFilter"></slot>
                    </div>

                    <!-- 高级搜索按钮 -->
                    <div v-if="hasFilter" class="fl marr-5">
                        <el-button @click="isShowFilter = true" type="warning">
                            <el-icon>
                                <Filter />
                            </el-icon>
                        </el-button>
                    </div>

                    <!-- 放大镜搜索按钮 -->
                    <div v-if="hasSearch" class="fl marr-5">
                        <el-button @click="onSearchFilter" type="primary">
                            <el-icon>
                                <Search />
                            </el-icon>
                        </el-button>
                    </div>

                    <!-- 其它控件，在高级搜索右边的一些功能按钮 -->
                    <div class="fl">
                        <slot name="otherBtn"></slot>
                    </div>
                </div>

                <!-- 顶部右侧按钮 -->
                <div class="fr flex-justify-right">
                    <slot name="rightBtn"></slot>
                </div>
            </div>

            <!-- 高级搜索内容 -->
            <el-drawer v-model="isShowFilter" :with-header="false" :close-on-click-modal="true" :size="500">
                <!-- 具体搜索表单内容 -->
                <template #default>
                    <slot name="Advfilter"></slot>
                </template>

                <!-- 底部按钮 -->
                <template #footer>
                    <el-button @click="isShowFilter = false">关闭</el-button>
                    <el-button type="danger" @click="onClearFilter">清空</el-button>
                    <el-button type="primary" @click="onSearchFilter">搜索</el-button>
                </template>
            </el-drawer>
        </div>

        <!-- 表格外层div，用于控制高度 -->
        <div class="data-table" :style="{ height: divHeight }">
            <!-- 表格 -->
            <vxe-table class="my-table" ref="VxeTableRef" :data="data" :height="height" :border="border" :columnConfig="{ resizable: resizable }" :cell-class-name="cellClassName" :header-cell-class-name="headerCellClassName" v-bind="$attrs">
                <!-- 多选框 -->
                <vxe-column v-if="hasCheckbox" type="checkbox" width="40" :resizable="false"></vxe-column>

                <!-- 单选框 -->
                <vxe-column v-if="hasRadio" type="radio" width="40" :resizable="false"></vxe-column>

                <!-- 序号 -->
                <vxe-column v-if="hasSeq" title="序号" type="seq" width="50" :resizable="false"></vxe-column>

                <!-- ID -->
                <vxe-column v-if="hasID" title="ID" :field="autoIDFieldName" width="80" :resizable="false"></vxe-column>

                <!-- 默认插槽，用于填充列表中的列信息 -->
                <slot name="default"></slot>
            </vxe-table>
        </div>

        <!-- 分页器 -->
        <vxe-pager class="cusPager" v-if="hasPager" :current-page="pageIndex" :page-size="pageSize" :total="totalCount" @page-change="onPageChange"></vxe-pager>
    </div>
</template>

<script lang="ts" setup>
import { VxeTableInstance } from "vxe-table";

//组件可接收的属性
const props = defineProps({
    //******************************************************************************表格相关

    //表格的数据
    data: {
        type: Array,
        default: [],
    },
    //表格的高度，默认为auto，可选值：auto, %, px
    height: {
        type: [Number, String],
        default: "100%",
    },
    //表格外层div的高度；height为auto时，需要设置外层div的高度
    divHeight: {
        type: String,
        default: "calc(100vh - 195px)", //这里的 193 = 头部(55) + tab(53) + 搜索(37) + 分页(40) + 表格上间距的和(10，下间距与分页的40重了10)
    },
    //是否显示表格边框
    border: {
        type: Boolean,
        default: true,
    },
    //是否可调整列宽
    resizable: {
        type: Boolean,
        default: true,
    },
    //是否显示复选框
    hasCheckbox: {
        type: Boolean,
        default: true,
    },
    //是否显示单选框
    hasRadio: {
        type: Boolean,
        default: false,
    },
    //是否显示序号列
    hasSeq: {
        type: Boolean,
        default: Config._IS_SHOW_SEQ,
    },
    //是否显示ID列
    hasID: {
        type: Boolean,
        default: Config._IS_SHOW_ID,
    },
    //是否显示分页器
    hasPager: {
        type: Boolean,
        default: true,
    },

    //autoID字段名
    autoIDFieldName: {
        type: String,
        default: "autoID",
    },

    //是否给表格行中下边框用特殊颜色
    isColorBottomBorder: {
        type: Boolean,
        default: false,
    },

    //给表格行中下边框设置颜色的行索引
    bottomBorderIndex: {
        type: Array<Number>,
        default: [0],
    },

    //需要设置必填项的列
    requiredArr: {
        type: Array,
        default: [],
    },

    //******************************************************************************分页器相关

    //当前页面
    pageIndex: {
        type: Number,
        default: 1,
    },
    //每页数据条数
    pageSize: {
        type: Number,
        default: 20,
    },
    //总数据条数
    totalCount: {
        type: Number,
        default: 0,
    },

    //******************************************************************************顶部以及高级搜索相关

    //是否显示表格上面的功能区域
    hasTop: {
        type: Boolean,
        default: true,
    },
    //是否显示添加按钮
    hasAdd: {
        type: Boolean,
        default: true,
    },
    //是否显示搜索文本框
    hasInput: {
        type: Boolean,
        default: false,
    },
    //是否显示高级搜索按钮
    hasFilter: {
        type: Boolean,
        default: true,
    },
    //是否显示搜索按钮
    hasSearch: {
        type: Boolean,
        default: true,
    },
    //搜索文本框中显示的提示内容
    inputTips: {
        type: String,
        default: null,
    },
});

//分页改变事件
const onPageChange = (pageData: any) => {
    emits("pageChange", pageData);
};

//searchInput文本改变事件
const searchInput = ref("");
const onInputChange = () => {
    emits("inputChange", searchInput.value);
};

//是否显示高级搜索
const isShowFilter = ref(false);

//高级搜索的搜索按钮点击事件
const onSearchFilter = () => {
    emits("searchFilter");
    isShowFilter.value = false;
};

//高级搜索的清空按钮点击事件
const onClearFilter = () => {
    emits("clearFilter");
    isShowFilter.value = false;
};

//vxe-table对象，此对象也被抛出供父组件可调用，在父组件使用时，不用在写DataTableRef.value，直接使用DataTableRef即可
const VxeTableRef = ref({} as VxeTableInstance);

//获取选中的行数据
const GetSelectData = (): Array<any> | any => {
    if ((props.hasCheckbox == true && props.hasRadio == true) || (props.hasCheckbox == false && props.hasRadio == false)) {
        throw new Error("如果要使用此方法，单选框和多选框只能出现一种！");
    }

    if (props.hasCheckbox) {
        //如果是多选框，则返回数组
        return Gx.DeepCopy(VxeTableRef.value.getCheckboxRecords()) as Array<any>;
    } else if (props.hasRadio) {
        //如果是单选框，则返回对象
        return Gx.DeepCopy(VxeTableRef.value.getRadioRecord()) as any;
    }
};

//获取选中行数据中一个属性
const GetSelectProp = (key: string = props.autoIDFieldName): Array<any> | any => {
    let _data = GetSelectData();

    if (props.hasCheckbox) {
        //如果是多选框，则返回数组
        return (_data as Array<any>).map((item) => {
            return item[key];
        });
    } else if (props.hasRadio) {
        //如果是单选框，则返回属性值
        return Gx.IsEmpty(_data) ? null : (_data as any)[key];
    }
};

//获取选中行数据的索引
const GetSelectIndex = (key: string = props.autoIDFieldName): Array<number> | number => {
    let _data = GetSelectData();

    if (props.hasCheckbox) {
        //如果是多选框，则返回数组
        let idx = [];
        _data.forEach((item) => {
            let _idx = props.data.findIndex((x) => {
                return x[key] == item[key];
            });

            idx.push(_idx);
        });

        return idx;
    } else if (props.hasRadio) {
        //如果是单选框，则返回属性值
        return props.data.findIndex((x) => {
            return x[key] == _data[key];
        });
    }
};

//设置默认选中的数据
//如果是要数据初始化完成就要默认选中，则需要调用 nextTick
const SetSelectData = (data: Array<any> | any, key: string = props.autoIDFieldName, isCheck: boolean = true) => {
    if ((props.hasCheckbox == true && props.hasRadio == true) || (props.hasCheckbox == false && props.hasRadio == false)) {
        throw new Error("如果要使用此方法，单选框和多选框只能出现一种！");
    }

    if (Gx.IsEmpty(data) || data.length == 0) {
        return;
    }

    if (props.hasCheckbox) {
        //因为是多选，为了保证代码不出错，当传入的数据不是数组时，把数据改成数组
        if (data.constructor != Array) {
            data = [data];
        }

        let _findList = props.data.filter((item: any) => {
            return (data as Array<any>).includes(item[key]);
        });

        VxeTableRef.value.setCheckboxRow(_findList, isCheck);
    } else if (props.hasRadio) {
        //因为是单选，为了保证代码不出错，当传入的数据是数组时，只取数据的第一个值
        if (data.constructor == Array) {
            data = data[0];
        }

        let _findData = props.data.find((item: any) => item[key] == data);

        VxeTableRef.value.setRadioRow(_findData);
    }
};

//给行添加class
const cellClassName = (row) => {
    let idx = props.bottomBorderIndex.findIndex((x) => x == row.rowIndex);
    if (props.isColorBottomBorder && idx != -1) {
        return "firshRow";
    }
};

//设置列表头添加class
const headerCellClassName = ({ column }) => {
    if (props.requiredArr.indexOf(column.title) !== -1) {
        return "requiredCell";
    }
};

//打开详情页点击事件
const onShowDetail = () => {
    emits("showDetail");
};

//定义向外抛出的事件
const emits = defineEmits(["pageChange", "inputChange", "showDetail", "searchFilter", "clearFilter"]);

//定义向外抛出的属性或方法
defineExpose({ searchInput, VxeTableRef, GetSelectData, GetSelectProp, GetSelectIndex, SetSelectData });
</script>

<style lang="scss" scoped>
//修改表格的内边距
.my-table :deep(.vxe-body--column) {
    padding: 5px !important;

    .vxe-cell {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
    .c--tooltip {
        width: calc(100% - 10px) !important;
    }
}

//处理分页按钮样式，不加底边，处理文字对不齐
.cusPager {
    border: 0 !important;
}
.cusPager :deep(.is--controls) {
    display: flex;
}
.cusPager :deep(.vxe-pager--jump) {
    height: 2.15rem;
    line-height: 2.15rem;
}
.cusPager :deep(.vxe-pager--total) {
    height: 2.15rem;
    line-height: 2.15rem;
}
</style>

<style lang="scss">
@import "@/assets/css/variables.scss";

//第一行为添加行时，给底线换颜色
.firshRow {
    border-bottom: 1px solid $color-primary;
}
</style>
